﻿// -------------------------------------------------------------------------------------------------------------------------------
// <copyright file="CrcsSparseSymmetricMatrixTriangularMatrixOperationsProvider.cs" company="Exul">
//     Copyright (c) Exul. All rights reserved.
// </copyright>
// <author>
//     Exul
// </author>
// -------------------------------------------------------------------------------------------------------------------------------

namespace ExulLibrary.Mathematics.LinearAlgebra.Sequential.DecimalExtensions
{
    #region Usings

    using System;

    using ExulLibrary.Mathematics.LinearAlgebra.Exceptions;

    #endregion

    /// <summary>
    ///     Provides operations for <see cref="CrcsSparseSymmetricMatrix{T}"/> through interface.
    /// </summary>
    internal sealed class CrcsSparseSymmetricMatrixTriangularMatrixOperationsProvider
        : ITriangularMatrixOperationsProvider<decimal>
    {
        #region Implemented Interfaces

        #region ITriangularMatrixOperationsProvider<decimal>

        /// <summary>
        ///     Solves a system of linear algebraic equations with the specified matrix and the right-hand part and
        ///     stores the result in the right-hand part vector.
        /// </summary>
        /// <param name="matrix">
        ///     The matrix of system.
        /// </param>
        /// <param name="rightHandPart">
        ///     The right-hand part vector as input and the result vector as output.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="matrix"/> is <see lagnword="null"/>.
        ///     <para>
        ///         --or--
        ///     </para>
        ///     <para>
        ///         <paramref name="rightHandPart"/> is <see lagnword="null"/>.
        ///     </para>
        /// </exception>
        /// <exception cref="NonSquareMatrixException">
        ///     <paramref name="matrix"/> is non-square matrix.
        /// </exception>
        /// <remarks>
        ///     The size of system to solve is determined as minimal value from size of <paramref name="matrix"/> and
        ///     length of <paramref name="rightHandPart"/>.
        /// </remarks>
        public void SolveWithDiagonal(Matrix<decimal> matrix, DenseVector<decimal> rightHandPart)
        {
            var realMatrix = matrix as CrcsSparseSymmetricMatrix<decimal>;
            realMatrix.SolveWithDiagonal(rightHandPart);
        }

        /// <summary>
        ///     Solves a system of linear algebraic equations with the specified matrix and the right-hand part and
        ///     stores the result in the right-hand part vector.
        /// </summary>
        /// <param name="matrix">
        ///     The matrix of system.
        /// </param>
        /// <param name="rightHandPart">
        ///     The right-hand part vector as input and the result vector as output.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="matrix"/> is <see lagnword="null"/>.
        ///     <para>
        ///         --or--
        ///     </para>
        ///     <para>
        ///         <paramref name="rightHandPart"/> is <see lagnword="null"/>.
        ///     </para>
        /// </exception>
        /// <exception cref="NonSquareMatrixException">
        ///     <paramref name="matrix"/> is non-square matrix.
        /// </exception>
        /// <remarks>
        ///     The size of system to solve is determined as minimal value from columns count of <paramref name="matrix"/> and
        ///     length of <paramref name="rightHandPart"/>.
        /// </remarks>
        public void SolveWithHighTriangle(Matrix<decimal> matrix, DenseVector<decimal> rightHandPart)
        {
            var realMatrix = matrix as CrcsSparseSymmetricMatrix<decimal>;
            realMatrix.SolveWithHighTriangle(rightHandPart);
        }

        /// <summary>
        ///     Solves a system of linear algebraic equations with the specified matrix and the right-hand part and
        ///     stores the result in the right-hand part vector.
        /// </summary>
        /// <param name="matrix">
        ///     The matrix of system.
        /// </param>
        /// <param name="rightHandPart">
        ///     The right-hand part vector as input and the result vector as output.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="matrix"/> is <see lagnword="null"/>.
        ///     <para>
        ///         --or--
        ///     </para>
        ///     <para>
        ///         <paramref name="rightHandPart"/> is <see lagnword="null"/>.
        ///     </para>
        /// </exception>
        /// <exception cref="NonSquareMatrixException">
        ///     <paramref name="matrix"/> is non-square matrix.
        /// </exception>
        /// <remarks>
        ///     The size of system to solve is determined as minimal value from columns count of <paramref name="matrix"/> and
        ///     length of <paramref name="rightHandPart"/>.
        /// </remarks>
        public void SolveWithHighTriangleAndDiagonal(Matrix<decimal> matrix, DenseVector<decimal> rightHandPart)
        {
            var realMatrix = matrix as CrcsSparseSymmetricMatrix<decimal>;
            realMatrix.SolveWithHighTriangleAndDiagonal(rightHandPart);
        }

        /// <summary>
        ///     Solves a system of linear algebraic equations with the specified matrix and the right-hand part and
        ///     stores the result in the right-hand part vector.
        /// </summary>
        /// <param name="matrix">
        ///     The matrix of system.
        /// </param>
        /// <param name="rightHandPart">
        ///     The right-hand part vector as input and the result vector as output.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="matrix"/> is <see lagnword="null"/>.
        ///     <para>
        ///         --or--
        ///     </para>
        ///     <para>
        ///         <paramref name="rightHandPart"/> is <see lagnword="null"/>.
        ///     </para>
        /// </exception>
        /// <exception cref="NonSquareMatrixException">
        ///     <paramref name="matrix"/> is non-square matrix.
        /// </exception>
        /// <remarks>
        ///     The size of system to solve is determined as minimal value from rows count of <paramref name="matrix"/> and
        ///     length of <paramref name="rightHandPart"/>.
        /// </remarks>
        public void SolveWithLowTriangle(Matrix<decimal> matrix, DenseVector<decimal> rightHandPart)
        {
            var realMatrix = matrix as CrcsSparseSymmetricMatrix<decimal>;
            realMatrix.SolveWithLowTriangle(rightHandPart);
        }

        /// <summary>
        ///     Solves a system of linear algebraic equations with the specified matrix and the right-hand part and
        ///     stores the result in the right-hand part vector.
        /// </summary>
        /// <param name="matrix">
        ///     The matrix of system.
        /// </param>
        /// <param name="rightHandPart">
        ///     The right-hand part vector as input and the result vector as output.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="matrix"/> is <see lagnword="null"/>.
        ///     <para>
        ///         --or--
        ///     </para>
        ///     <para>
        ///         <paramref name="rightHandPart"/> is <see lagnword="null"/>.
        ///     </para>
        /// </exception>
        /// <exception cref="NonSquareMatrixException">
        ///     <paramref name="matrix"/> is non-square matrix.
        /// </exception>
        /// <remarks>
        ///     The size of system to solve is determined as minimal value from rows count of <paramref name="matrix"/> and
        ///     length of <paramref name="rightHandPart"/>.
        /// </remarks>
        public void SolveWithLowTriangleAndDiagonal(Matrix<decimal> matrix, DenseVector<decimal> rightHandPart)
        {
            var realMatrix = matrix as CrcsSparseSymmetricMatrix<decimal>;
            realMatrix.SolveWithLowTriangleAndDiagonal(rightHandPart);
        }

        #endregion

        #endregion
    }
}